package jccr;

import java.util.LinkedList;

public abstract class Port<T> implements Queue<T>, RawPort {
	
	public void enqueue( T arg ) {
		
		Coordinator coord = null;
		
		synchronized( _posts ) {
			
			_posts.addFirst(arg);
			coord = _coordinator;
		}			
		
		// start a coordination operation of coordinator is available
		if ( coord != null )
			coord.asyncCoordinate( this );
	}
	
	public T dequeue() {
		
		synchronized ( _posts ) { 
			// only remove if there is an element available
			return _posts.size() > 0 ? _posts.removeLast() : null; 
		}
	}
	
	public int count() {
		
		synchronized( _posts ) {
			return _posts.size();
		}
	}
	
	public Object dequeueRaw() {
		return dequeue();
	}
	
	@SuppressWarnings("unchecked")
	public void executeRaw( Object arg ) {
		execute( (T)arg );
	}
	
	public abstract void execute( T arg );
	
	public void setCoordinator( Coordinator coordinator ) {
				
		_coordinator = coordinator;
		
		/* whenever we get a new valid coordinator request a coordination
		 * to avoid dangling arguments in my internal queue
		 */
		if ( _coordinator != null )
			_coordinator.asyncCoordinate(this);
	}
	
	Coordinator _coordinator;
	LinkedList<T> _posts = new LinkedList<T>();
}

